package org.shangrila.app.wfm.mb;

import java.util.Collections;
import java.util.Comparator;
import java.util.StringTokenizer;

import org.primefaces.model.diagram.Connection;
import org.primefaces.model.diagram.DefaultDiagramModel;
import org.primefaces.model.diagram.Element;
import org.primefaces.model.diagram.connector.FlowChartConnector;
import org.primefaces.model.diagram.endpoint.BlankEndPoint;
import org.primefaces.model.diagram.endpoint.EndPoint;
import org.primefaces.model.diagram.endpoint.EndPointAnchor;
import org.primefaces.model.diagram.overlay.ArrowOverlay;
import org.primefaces.model.diagram.overlay.LabelOverlay;
import org.shangrila.wfm.eo.WfmProcess;
import org.shangrila.wfm.eo.WfmNode;
import org.shangrila.wfm.eo.WfmTransition;
//import org.slf4j.Logger;
//import org.slf4j.LoggerFactory;

public class WfmDiagramModel {
	//private static final Logger logger = LoggerFactory.getLogger(WfmDiagramModel.class);
	
	public WfmDiagramModel() {
	}

    /**
     * 根据流程实例显示流程图，并且配置当前节点显示风格: 图节点ID为WfmNodes.name
     * @param selectedProcess
     * @param pNodeName 
     * @return
     */
    public static DefaultDiagramModel genProcessDiagramModel(WfmProcess selectedProcess,String pNodeName) {
    	DefaultDiagramModel model;
    	//log.info("selectedProcess:"+selectedProcess.getId());
    	model = new DefaultDiagramModel();
        model.setMaxConnections(-1);
        FlowChartConnector connector = new FlowChartConnector();
        connector.setPaintStyle("{strokeStyle:'#C7B097',lineWidth:2}");
        model.setDefaultConnector(connector);
        
        //对节点排序：Seqno
        Collections.sort(selectedProcess.getWfmNodes(),new Comparator<WfmNode>(){
            public int compare(WfmNode arg0, WfmNode arg1) {
                return arg0.getSeqno().compareTo(arg1.getSeqno());
            }
        });
        
	    //根据节点排序生成节点:使用节点layout信息作为em值来显示在画面上
	    for(WfmNode wpn:selectedProcess.getWfmNodes()){
	    	 Element element = new Element(wpn.getDisplayName(),useStringTokenizer(wpn.getLayout(),",")[0]+"em", useStringTokenizer(wpn.getLayout(),",")[1]+"em");
	    	 element.addEndPoint(createEndPoint(EndPointAnchor.LEFT));
	    	 element.addEndPoint(createEndPoint(EndPointAnchor.RIGHT));

	    	 element.setId(wpn.getName());  //只能使用ID查找Element 否则使用mapParentModes.put(wpn.getName(),element.getId());
	 
			 if("start".equalsIgnoreCase(wpn.getName()))
				 element.setStyleClass("ui-diagram-start");
			 else if ("end".equalsIgnoreCase(wpn.getName()))
				 element.setStyleClass("ui-diagram-end");
			 
			 //配置当前节点显示风格
			 if(null!=pNodeName && pNodeName.equalsIgnoreCase(wpn.getName()) )
				 element.setStyleClass("ui-diagram-focus");//设置当前节点的特殊颜色
			 
			 model.addElement(element);			 
	    }
	    
	    //根据节点生成连接
	    for(Element em:model.getElements()){
	    	for(WfmTransition wpt:selectedProcess.getWfmTransitions()){ //建立连接	    		
	    		if(em.getId().equalsIgnoreCase(wpt.getFromNode())) {  
	    			//logger.info(em.getId()+"--"+wpt.getToNode()+"--"+wpt.getDisplayName());
    				model.connect(createConnection(em.getEndPoints().get(1), model.findElement(wpt.getToNode()).getEndPoints().get(0), wpt.getDisplayName()));	    		
	    		}
	        }
	    }

    	return model;
    }

    /**
     * 根据流程实例显示流程图，并且配置当前节点显示风格: 图节点ID为WfmNodes.Seqno
     * @param selectedProcess
     * @param pNodeName 
     * @return
     */
    public static DefaultDiagramModel ggenDiagramModel(WfmProcess selectedProcess,String pNodeName) {
    	DefaultDiagramModel model;
    	//log.info("selectedProcess:"+selectedProcess.getId());
    	model = new DefaultDiagramModel();
        model.setMaxConnections(-1);
        FlowChartConnector connector = new FlowChartConnector();
        connector.setPaintStyle("{strokeStyle:'#C7B097',lineWidth:2}");
        model.setDefaultConnector(connector);
        
        //对节点排序：Seqno
        Collections.sort(selectedProcess.getWfmNodes(),new Comparator<WfmNode>(){
            public int compare(WfmNode arg0, WfmNode arg1) {
                return arg0.getSeqno().compareTo(arg1.getSeqno());
            }
        });
        
	    //根据节点排序生成节点:使用节点layout信息作为em值来显示在画面上
	    for(WfmNode wpn:selectedProcess.getWfmNodes()){
	    	 Element element = new Element(wpn.getDisplayName(),useStringTokenizer(wpn.getLayout(),",")[0]+"em", useStringTokenizer(wpn.getLayout(),",")[1]+"em");
	    	 element.addEndPoint(createEndPoint(EndPointAnchor.LEFT));
	    	 element.addEndPoint(createEndPoint(EndPointAnchor.RIGHT));

	    	 element.setId(wpn.getSeqno());  //只能使用ID查找Element 否则使用mapParentModes.put(wpn.getName(),element.getId());
	 
			 if("start".equalsIgnoreCase(wpn.getName()))
				 element.setStyleClass("ui-diagram-start");
			 else if ("end".equalsIgnoreCase(wpn.getName()))
				 element.setStyleClass("ui-diagram-end");
			 			 
			 //配置当前节点显示风格
			 if(null!=pNodeName && pNodeName.equalsIgnoreCase(wpn.getName()) )
				 element.setStyleClass("ui-diagram-focus");//设置当前节点的特殊颜色
			 
			 model.addElement(element);			 
	    }
	    
	    //根据节点生成连接
	    for(Element em:model.getElements()){
	    	for(WfmTransition wpt:selectedProcess.getWfmTransitions()){ //建立连接	    		
	    		if(em.getId().equalsIgnoreCase(wpt.getFromSeqno())) {  //wpt.getFromNode()
	    			//logger.info(em.getId()+"--"+wpt.getToNode()+"--"+wpt.getDisplayName());
    				model.connect(createConnection(em.getEndPoints().get(1), model.findElement(wpt.getToSeqno()).getEndPoints().get(0), wpt.getDisplayName()));	    		
	    		}
	        }
	    }
		 
    	return model;
    }

    private static EndPoint createEndPoint(EndPointAnchor anchor) {
    	BlankEndPoint endPoint = new BlankEndPoint(anchor);
        endPoint.setStyle("{fillStyle:'#404a4e'}");
        endPoint.setHoverStyle("{fillStyle:'#20282b'}");
         
        return endPoint;
    }
    private static Connection createConnection(EndPoint from, EndPoint to, String label) {
        Connection conn = new Connection(from, to);
        conn.getOverlays().add(new ArrowOverlay(8, 8, 1, 1));         
        if(label != null) {
            conn.getOverlays().add(new LabelOverlay(label, "flow-label", 0.5));
        }         
        return conn;
    }
       
	/**
	 * 利用StringTokenizer来进行字符串分割
	 * @param str    待分割的字符串
	 * @param sdelimiter     分割符
	 * @return
	 */
	public static String[] useStringTokenizer(String str, String sdelimiter) {
		StringTokenizer token = new StringTokenizer(str, sdelimiter);
		String[] array = new String[token.countTokens()];
		int i = 0;
		while (token.hasMoreTokens()) {
			array[i] = token.nextToken();
			i++;
		}
		return array;
	}

}
